查看原文
其他

C++ initializer_list 详解

CPP开发者 2021-07-20

(给CPP开发者加星标,提升C/C++技能)

来源:Rotation.
https://blog.csdn.net/fengxinlinux/article/details/72614874

【导读】:模板initializer_list是C++11中新增的,用于可让我们列表初始化容器,自定义的函数,自定义的类中的构造函数,要在代码中使用initializer_list必须包含头文件initializer_list,这个模板很简单,包含成员函数 begin(),end(),size(),可以使用这些函数去遍历列表元素。


以下是正文


initializer_list是C++11提供的新类型,定义在头文件中。


用于表示某种特定类型的值的数组,和vector一样,initializer_list也是一种模板类型。

template< class T >class initializer_list;

要介绍initializer_list的使用,有必要先谈一谈列表初始化。


C++11扩大了初始化列表的适用范围,使其可用于所有内置类型和用户定义的类型。无论是初始化对象还是某些时候为对象赋新值,都可以使用这样一组由花括号括起来的初始值了。使用初始化列表时,可添加=,也可不添加。

//定义一个变量并初始化int units_sold=0;int units_sold(0);int units_sold={0}; //列表初始化int units_sold{0}; //列表初始化

当初始化列表用于内置类型的变量时,这种初始化形式有一个重要特点:如果我们使用列表初始化值存在丢失信息的风险,则编译器将报错:

long double ld=3.1415926536;int a={ld},b={ld}; //错误:转换未执行,因为存在丢失信息的风险int c(ld),d=ld; //正确:转换执行,且确实丢失了部分值

列表初始化就谈到这里,接下来介绍initializer_list的使用


它提供的操作如下:

initializer_list<T> lst; //默认初始化;T类型元素的空列表initializer_list<T> lst{a,b,c...};//lst的元素数量和初始值一样多;lst的元素是对应初始值的副本lst2(lst) lst2=lst //拷贝或赋值一个initializer_list对象不会拷贝列表中的元素;拷贝后,原始列表和副本元素共享lst.size() //列表中的元素数量lst.begin() //返回指向lst中首元素的指针lst.end() //返回指向lst中尾元素下一位置的指针

需要注意的是,initializer_list对象中的元素永远是常量值,我们无法改变initializer_list对象中元素的值。并且,拷贝或赋值一个initializer_list对象不会拷贝列表中的元素,其实只是引用而已,原始列表和副本共享元素。


和使用vector一样,我们也可以使用迭代器访问initializer_list里的元素

void error_msg(initializer_list<string> il){ for(auto beg=il.begin();beg!=il.end();++beg) cout<<*beg<<" "; cout<<endl;}

如果想向initializer_list形参中传递一个值的序列,则必须把序列放在一对花括号内:

//expected和actual是string对象if(expected != actual) error_msg({"functionX",expectde,actual});else error_msg({"functionX","okay"});

说了这么多,那initializer_list到底有什么应用呢?


有了initializer_list之后,对于STL的container的初始化就方便多了,比如以前初始化一个vector需要这样:

std::vector v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);

而现在c++11添加了initializer_list后,我们可以这样初始化

std::vector v = { 1, 2, 3, 4 };

并且,C++11允许构造函数和其他函数把初始化列表当做参数。

#include <iostream>#include <vector>
class MyNumber{public: MyNumber(const std::initializer_list<int> &v) { for (auto itm : v) { mVec.push_back(itm); } }
void print() { for (auto itm : mVec) { std::cout << itm << " "; } }private: std::vector<int> mVec;};
int main(){ MyNumber m = { 1, 2, 3, 4 }; m.print(); // 1 2 3 4
return 0;}


- EOF -


推荐阅读  点击标题可跳转

1、TinyXML2 使用方法及示例

2、C++ explicit 关键字详解

3、C++20 标准正式发布


关于 C++ initializer_list 详解,欢迎在评论中和我探讨。觉得文章不错,请点赞和在看支持我继续分享好文。谢谢!


关注『CPP开发者』

看精选C++技术文章 . 加C++开发者专属圈子

↓↓↓


点赞和在看就是最大的支持❤️

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存